package com.dingding.study.service.日志记录;

import com.alibaba.fastjson.JSONArray;
import com.dingding.study.DTO.LogDTO;
import com.dingding.study.annotation.ApiLog;
import com.dingding.study.mapper.LogMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;

@EnableAspectJAutoProxy
@Component
@Aspect
public class RecordLog {

    @Autowired
    private LogMapper logMapper;

    @Pointcut("@annotation(com.dingding.study.annotation.ApiLog)")
    public void logPointCut(){};

    @Around(value = "logPointCut()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = null;
        String methodName = joinPoint.getSignature().getName();

        Object target = joinPoint.getTarget();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = target.getClass().getMethod(signature.getName(), signature.getParameterTypes());
        ApiLog annotation = method.getAnnotation(ApiLog.class);
        String moduleName = annotation.moduleName();
        String methodDesc = annotation.methodDesc();

        Object[] args = joinPoint.getArgs();

        LogDTO logDTO = new LogDTO();
        logDTO.setModuleName(moduleName);
        logDTO.setMethodDesc(methodDesc);
        logDTO.setMethodParams(new JSONArray(Arrays.asList(args)).toString());
        logDTO.setMethodName(methodName);

        result = joinPoint.proceed();
        String resultJson = JSONArray.toJSON(result).toString();
        logDTO.setMethodResult(resultJson);
        //System.out.println(logDTO);
        System.out.println(Thread.currentThread().getName());
        insertLog(logDTO);
        return result;
    }

    @Async
    public void insertLog(LogDTO logDTO) {
        System.out.println(Thread.currentThread().getName());
        logMapper.insert(logDTO);
    }
}
